<script setup lang="ts">
import { ref, onMounted, watch, onBeforeUnmount } from 'vue'
import * as echarts from 'echarts/core'
import { GaugeChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers'

echarts.use([GaugeChart, CanvasRenderer])

const props = defineProps({
  // 基础配置
  width: { type: Number, default: 200 },
  height: { type: Number, default: 200 },
  value: { type: Number, default: 0 },
  title: { type: String, default: '' },
  
  // 仪表盘范围
  min: { type: Number, default: 0 },
  max: { type: Number, default: 100 },
  
  // 样式配置
  radius: { type: Number, default: 80 }, // 仪表盘半径
  centerX: { type: Number, default: 50 }, // 中心点X坐标（百分比）
  centerY: { type: Number, default: 50 }, // 中心点Y坐标（百分比）
  
  // 指针配置
  pointerLength: { type: Number, default: 50 }, // 指针长度
  pointerWidth: { type: Number, default: 3 }, // 指针宽度
  
  // 刻度配置
  splitNumber: { type: Number, default: 10 }, // 分割段数
  axisLineWidth: { type: Number, default: 12 }, // 轴线宽度
  axisTick: { type: Boolean, default: true }, // 是否显示刻度
  axisTickLength: { type: Number, default: 6 }, // 刻度长度
  axisTickDistance: { type: Number, default: -12 }, // 刻度距离
  
  // 文字配置
  fontSize: { type: Number, default: 10 }, // 文字大小
  detailFontSize: { type: Number, default: 12 }, // 详情文字大小
  unit: { type: String, default: 'px' }, // 单位
  
  // 颜色配置
  colors: { 
    type: Array, 
    default: () => [
      [0.3, '#67e0e3'],
      [0.7, '#37a2da'],
      [1, '#fd666d']
    ]
  },
  textColor: { type: String, default: '#fff' },
})

const chartDom = ref<HTMLElement | null>(null)
let chart: echarts.ECharts | null = null

const initChart = () => {
  if (chartDom.value) {
    chart = echarts.init(chartDom.value)
    updateChart()
  }
}

const resizeHandler = () => {
  chart?.resize()
}

onMounted(() => {
  initChart()
  window.addEventListener('resize', resizeHandler)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeHandler)
  chart?.dispose()
})

const updateChart = () => {
  if (!chart) return
  
  const option = {
    series: [{
      type: 'gauge',
      min: props.min,
      max: props.max,
      splitNumber: props.splitNumber,
      radius: props.radius + '%',
      center: [props.centerX + '%', props.centerY + '%'],
      
      axisLine: {
        lineStyle: {
          width: props.axisLineWidth,
          color: props.colors
        }
      },
      
      pointer: {
        length: props.pointerLength,
        width: props.pointerWidth,
        itemStyle: {
          color: props.textColor
        }
      },
      
      axisTick: {
        show: props.axisTick,
        distance: props.axisTickDistance,
        length: props.axisTickLength,
        lineStyle: {
          color: props.textColor,
          width: 1
        }
      },
      
      splitLine: {
        distance: props.axisTickDistance,
        length: props.axisTickLength + 4,
        lineStyle: {
          color: props.textColor,
          width: 2
        }
      },
      
      axisLabel: {
        color: props.textColor,
        distance: Math.abs(props.axisTickDistance) + 10,
        fontSize: props.fontSize
      },
      
      title: {
        show: props.title !== '',
        offsetCenter: [0, '60%'],
        fontSize: props.fontSize,
        color: props.textColor,
        formatter: props.title
      },
      
      detail: {
        show: false
      },
      
      data: [{
        value: props.value
      }]
    }]
  }
  
  chart.setOption(option)
}

// 监听属性变化
watch(() => props, () => {
  updateChart()
}, { deep: true })
</script>

<template>
  <div class="gauge-container">
    <div 
      ref="chartDom" 
      :style="{ 
        width: '100%', 
        height: '100%' 
      }"
    ></div>
    <slot :value="value" :unit="unit">
      <!-- 默认插槽内容 -->
      <div class="gauge-value">
        {{ value }}{{ unit }}
      </div>
    </slot>
  </div>
</template>

<style scoped>
.gauge-container {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gauge-value {
  position: absolute;
  bottom: 15%;
  font-size: v-bind('detailFontSize + "px"');
  color: v-bind('textColor');
  font-weight: bold;
}
</style> 